import requests
from bs4 import BeautifulSoup
import json
import os
import re
import sys


def download_bing_images(num_images=4):
    """
    从必应图片搜索下载指定数量的宠物壁纸4k图片

    Args:
        num_images (int): 要下载的图片数量，默认为4张
    """
    # 1.发送请求
    url = "https://cn.bing.com/images/search?q=%E5%AE%A0%E7%89%A9%E5%A3%81%E7%BA%B84k&form=IACFSM&first=1&cw=1644&ch=941"
    response = requests.get(url)

    # 2.检查请求是否成功
    if response.status_code != 200:
        print(f"网页请求失败，状态码：{response.status_code}")
        return False

    # 3.解析html内容
    page = BeautifulSoup(response.text, "html.parser")

    # 4.查找所有的图片元素
    image_elements = page.find_all('a', class_="iusc")
    if not image_elements:
        print("未找到图片元素")
        return False

    print(f"找到 {len(image_elements)} 张图片，准备下载前{num_images}张")

    # 5.创建下载目录
    download_dir = r"D:\Python\宠物壁纸4k"
    if not os.path.exists(download_dir):
        os.makedirs(download_dir)
        print(f"创建目录: {download_dir}")

    # 6.设置请求头，模拟浏览器访问
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }

    # 7.记录下载结果
    success_count = 0
    failed_count = 0
    failed_list = []

    # 8.下载指定数量的图片
    for i, element in enumerate(image_elements[:num_images]):
        try:
            # ①获取m属性的JSON数据
            m_data = element.get("m")
            if not m_data:
                print(f"第{i + 1}张图片无m数据，跳过")
                failed_count += 1
                failed_list.append(f"图片{i + 1}: 无m数据")
                continue

            # ②解析JSON数据
            image_info = json.loads(m_data)
            image_url = image_info.get("murl")
            image_title = image_info.get("t", f"image_{i}")

            if not image_url:
                print(f"第{i + 1}张图片无有效URL，跳过")
                failed_count += 1
                failed_list.append(f"图片{i + 1}: 无有效URL")
                continue

            # ③清理文件名（移除非法字符）
            clean_title = re.sub(r'[<>:"/\\|?*]', '', image_title)
            file_extension = os.path.splitext(image_url)[1]
            if not file_extension or len(file_extension) > 5:
                file_extension = '.jpg'

            # ④构建文件名和完整的文件路径
            filename = f"{clean_title}_{i}{file_extension}"
            filepath = os.path.join(download_dir, filename)

            # ⑤下载图片
            print(f"正在下载 ({i + 1}/{num_images}): {image_title}")
            img_response = requests.get(image_url, headers=headers, stream=True, timeout=30)

            if img_response.status_code == 200:
                # 保存图片文件
                with open(filepath, 'wb') as f:
                    for chunk in img_response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)

                # 验证文件是否真正下载成功
                if os.path.exists(filepath) and os.path.getsize(filepath) > 0:
                    print(f"✅ 成功保存: {filename}")
                    success_count += 1
                else:
                    print(f"❌ 文件保存失败: {filename}")
                    failed_count += 1
                    failed_list.append(f"图片{i + 1}: 文件保存失败")
            else:
                print(f"❌ 下载失败，HTTP状态码: {img_response.status_code}")
                failed_count += 1
                failed_list.append(f"图片{i + 1}: HTTP错误 {img_response.status_code}")

        except Exception as e:
            print(f"❌ 处理图片 {i + 1} 时出错: {str(e)}")
            failed_count += 1
            failed_list.append(f"图片{i + 1}: 异常 {str(e)}")

    # 9.最终结果报告
    print("\n" + "=" * 50)
    print("下载完成总结:")
    print(f"✅ 成功下载: {success_count} 张")
    print(f"❌ 下载失败: {failed_count} 张")

    if failed_list:
        print("\n失败详情:")
        for failure in failed_list:
            print(f"  - {failure}")

    # 10.检查目标文件夹中的图片文件
    downloaded_files = [f for f in os.listdir(download_dir) if
                        f.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp'))]
    print(f"\n目标文件夹中实际存在的图片文件: {len(downloaded_files)} 张")

    if downloaded_files:
        print("文件列表:")
        for file in downloaded_files:
            file_size = os.path.getsize(os.path.join(download_dir, file))
            print(f"  - {file} ({file_size} 字节)")

    # 11.如果有失败的情况，返回False并报错
    if failed_count > 0:
        print(f"\n❌ 错误: 有 {failed_count} 张图片下载失败!")
        return False
    else:
        print(f"\n✅ 所有图片下载成功!")
        return True


# 运行程序
if __name__ == "__main__":
    # 获取命令行参数（如果有）
    if len(sys.argv) > 1:
        try:
            num_images = int(sys.argv[1])
            print(f"将从命令行参数下载 {num_images} 张图片")
        except ValueError:
            print("⚠️ 无效的参数，使用默认值4张")
            num_images = 4
    else:
        num_images = 4  # 默认下载4张

    success = download_bing_images(num_images)
    if not success:
        # 如果有失败，可以在这里进行额外处理或报错
        exit(1)  # 非零退出码表示程序执行有错误
